import { BranchesOutlined, CloseCircleOutlined, CloudDownloadOutlined, RocketOutlined, SisternodeOutlined } from "@ant-design/icons";
import { Card, Col, Image, Modal, notification, Row } from "antd";
import Text from "antd/lib/typography/Text";
import $ from "jquery";
import React from "react";
import Typist from 'react-typist';
import "./BodyBuilder.css";
import DetailDrawerBuilder from "./DetailDrawerBuilder";
import DrawerBuilder from "./DrawerBuilder";
import { deserialize, RoutingStepArray } from "./geom/routinglib";
import RoutingStepBuilder from "./geom/RoutingStepBuilder";
import logo from "./img/logo.png";
import MapBuilder from "./MapBuilder";
import RecommendModel from "./RecommendModel";
import conf from "./runtime/configuration";
import WeatherInfoBuilder from "./WeatherInfoBuilder";

class IndexPageLogo extends React.Component {

    constructor(props) {
        super(props)
        this.state = { key: 0 }
    }

    initialSentence = "在国色天乡里 "

    sentenceList = [
        "有什么？",
        "有不可思议的……",
        "开启一段奇妙的旅程！"
    ]

    senBlk(prefix, dynamic) {
        let collector = [prefix, <Typist.Delay ms={500} />];

        for (const sen of dynamic) {
            collector.push(<span>{sen}</span>)
            collector.push(
                <Typist.Backspace count={sen.length} delay={1000} />
            )
        }

        let totalLength = prefix.length + dynamic.at(-1).length
        collector.push(<Typist.Backspace count={totalLength} />)
        return collector
    }

    render() {

        let children = []

        children.push(...this.senBlk("欢迎 ", ["来到国色天乡！"]))
        children.push(...this.senBlk("这里有 ", [
            "鬼屋？", "旋转木马？", "不可思议的……", "一切你想要的！"
        ]))
        children.push(...this.senBlk("让我们一起 ", [
            "放声尖叫(≧∀≦)",
            "享受无忧无虑的时光、",
            "进入这个奇妙的世界！"
        ]))

        let uniqueKey = this.state.key

        return (
            <Typist key={uniqueKey} className="index-page-typist"
                onTypingDone={() => this.setState({ key: uniqueKey + 1 })}>
                {children}
            </Typist>
        )
    }
}

class IndexPageBtn extends React.Component {

    normalBtnStyle = {
        backgroundColor: "#FFC955",
        color: "#3B2667",
        textAlign: 'center',
        fontWeight: 'bold',
        borderStyle: 'solid',
        borderColor: "#FFC955",
        borderRadius: '5px',
        marginTop: '20px',
    }

    activeBtnStyle = {
        color: "#FFC955",
        backgroundColor: "#3B2667",
        textAlign: 'center',
        fontWeight: 'bold',
        borderStyle: 'solid',
        borderColor: "#FFC955",
        borderRadius: '5px',
        marginTop: '20px',
    }

    firstTimeBtnStyleAnimation = $.extend(this.normalBtnStyle, {
        animationName: "first-time-btn",
        animationDuration: "0.5s",
        animationFillMode: 'both',
    })

    normalBtnStyleAnimation = $.extend(this.normalBtnStyle, {
        animationName: "normal-btn",
        animationDuration: '0.5s',
        animationFillMode: 'both',
    })

    activeBtnStyleAnimation = $.extend(this.activeBtnStyle, {
        animationName: "active-btn",
        animationDuration: "0.5s",
        animationFillMode: 'both',
    })

    constructor(props) {
        super(props)
        this.state = {
            normal: true,
            text: this.props.text
        }
    }

    onHover = e => {
        if (this.state.normal) {
            this.setState({
                normal: false,
                text: this.props.optText === undefined ?
                    this.props.text : this.props.optText
            })
        } else {
            this.setState({
                normal: true,
                text: this.props.text
            })
        }
    }

    firstTime = true

    render() {
        const btnStyle = this.firstTime ?
            this.firstTimeBtnStyleAnimation :
            this.state.normal ?
                this.normalBtnStyleAnimation : this.activeBtnStyleAnimation;
        this.firstTime = false
        const fontSize = this.props.fontSize === undefined ?
            '1.5em' : this.props.fontSize;
        return (
            <Card hoverable={true}
                onMouseEnter={this.onHover}
                onMouseLeave={this.onHover}
                onClick={this.props.onClick}
                cover={this.props.icon}
                style={btnStyle}
                bordered={false}>
                <span style={{ fontSize: fontSize, }}>
                    {this.state.text}
                </span>
            </Card>
        )
    }
}

export let ENTER_TYPE = 'NORM';

class MapWrapper extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            routingArray: new RoutingStepArray([]),
            showList: false,
            showConsole: false,
            showModal: false,
        }
    }

    addRouting = feature => {
        this.setState({
            routingArray: this.state.routingArray.append(feature),
        })
    }

    delRouting = index => {
        this.forceUpdate();
        this.setState({
            routingArray: this.state.routingArray.delete(index),
        })
    }

    findRouting = feature => this.state.routingArray.find(feature)

    updateRouting = (routing) => {
        this.setState({
            routingArray: routing,
            showList: true,
            showConsole: false,
        })
    }

    openMoreRouting = () => {
        this.setState({
            showModal: true,
        })
    }

    clearRouting = () => {
        this.setState({
            routingArray: new RoutingStepArray([]),
            showList: true,
            showConsole: false,
        })
    }

    openModal = () => {
        this.setState({ showModal: true })
    }

    closeModal = () => {
        this.setState({ showModal: false })
    }


    openSuccessDumpingModel = (name) => {
        Modal.success({
            title: "成功提交计划",
            content: (
                <span>
                    将计划名称
                    <Text strong style={{ color: "#3B2667" }}>
                        {name}
                    </Text>
                    告诉朋友，一起分享你的计划！
                </span>
            ),
        });
    };

    openFailedDumpingModel = (name) => {
        Modal.error({
            title: "成功提交计划",
            content: (
                <span>
                    计划名
                    <Text strong style={{ color: "brown" }}>
                        {name}
                    </Text>
                    提交失败！
                </span>
            ),
        });
    };


    dumpRouting = (name, routing) => {
        $.post(conf.url.backendServer + "/routing", {
            name: name, content: routing,
        }, response => {
            console.log(response)
            if (response.ok) {
                this.openSuccessDumpingModel(name);
            } else {
                this.openFailedDumpingModel(name);
                console.error(`RESPONSE=${response}`)
            }
        })
    }

    openSuccessLoadingModel = (name) => {
        notification.open({
            message: "成功加载",
            description: (
                <span>
                    成功加载计划<Text strong>{name}</Text>!
                </span>
            ),
            icon: <CloudDownloadOutlined />,
        });
    }

    openFailedLoadingModel = (name) => {
        notification.open({
            message: "加载失败",
            description: (
                <span>
                    加载<Text strong>{name}</Text>失败，请确认是否存在该计划！
                </span>
            ),
            icon: <CloseCircleOutlined />,
        });
    }

    loadRouting = (name) => {
        $.get(conf.url.backendServer + "/routing", {
            name: name
        }, (response) => {
            if (response.ok) {
                const newRouting = deserialize(response.content);
                this.updateRouting(newRouting);
                this.openSuccessLoadingModel(name);
            } else {
                this.openFailedLoadingModel(name);
            }
        })
    }

    render() {
        return (
            <>
                <Row style={conf.styles.header}
                    id="main-header"
                    className="dim-in">
                    <Col span={5} offset={1}>
                        <Image src={logo} alt="Logo" preview={false} />
                    </Col>
                    <Col span={9} offset={8}>
                        <WeatherInfoBuilder />
                    </Col>
                </Row>
                <MapBuilder className="dim-in"></MapBuilder>
                <DrawerBuilder
                    visible={this.state.showConsole}
                    routing={true}
                    openRoutingList={() => this.setState({ showList: true })}
                    closeRoutingList={() => this.setState({ showList: false })}
                    loadRouting={this.loadRouting}
                    clearRoutingList={this.clearRouting}
                    openMoreRouting={this.openModal}
                />
                <DetailDrawerBuilder
                    add={this.addRouting}
                    del={this.delRouting}
                    find={this.findRouting}
                    update={() => this.forceUpdate()}
                    routing={true} />
                <RoutingStepBuilder
                    visible={this.state.showList}
                    routingArray={this.state.routingArray}
                    dumpRouting={this.dumpRouting} />
                <RecommendModel visible={this.state.showModal}
                    closeModel={this.closeModal}
                    loadRouting={this.loadRouting} />
            </>
        )
    }
}

export default class BodyBuilder extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            isIndexPage: true,
        }
    }

    normallyEnterMap = () => {
        this.setState({
            isIndexPage: false,
        })
    }

    editingEnterMap = () => {
        ENTER_TYPE = 'EDIT'
        this.setState({
            isIndexPage: false,
        })
    }

    readingEnterMap = () => {
        ENTER_TYPE = 'READ'
        this.setState({
            isIndexPage: false,
        })
    }

    routeIcon = <BranchesOutlined className="btn-icon" />;
    makerIcon = <SisternodeOutlined className="btn-icon" />;

    indexPage = props => (
        <div id="index-page" className={props.className}
            style={{ paddingTop: '20px' }}>
            <div id="index-page-background">
                <Row>
                    <Col span={24}>
                        <IndexPageLogo />
                    </Col>
                </Row>
                <Row id="index-page-btns">
                    <Col span={8}>
                        <Row>
                            <Col offset={1} span={10}>
                                <IndexPageBtn text="热门计划"
                                    icon={this.routeIcon}
                                    onClick={this.readingEnterMap} />
                            </Col>
                            <Col offset={1} span={10}>
                                <IndexPageBtn text="制作计划"
                                    icon={this.makerIcon}
                                    onClick={this.editingEnterMap} />
                            </Col>
                            <Col offset={1} span={21}>
                                <IndexPageBtn text="或者…"
                                    onClick={this.normallyEnterMap}
                                    fontSize="2.5em"
                                    optText={
                                        <span>
                                            <RocketOutlined />
                                            <span>直接查看地图！</span>
                                        </span>
                                    } />
                            </Col>
                        </Row>
                    </Col>
                </Row>
            </div>
        </div>
    )


    render() {
        if (this.state.isIndexPage) {
            return (
                <>
                    <this.indexPage />
                    <Image src={logo} alt="Logo" preview={false}
                        style={{ display: "none" }} />
                </>
            )
        } else {
            const mapWrapper = this.state.arguments === 'NORM' ?
                <MapWrapper /> : <MapWrapper isFirstOpenRoutingList />;
            return (
                <>
                    <this.indexPage className="dim-out" />
                    {mapWrapper}
                </>
            )
        }
    }
}